<?php

class images {

	const LOCATION_ALL = 1;
	const LOCATION_GROUP = 2;
	const LOCATION_USER = 3;

	public static $allowedFiletypes = array("png", "gif", "jpg", "jpeg", "wmf", "svg", "x-wmf", "x-png", "pjpeg");

	public static function getUserLists(user &$userObj){
		/*
		SELECT isID, name, private, license
		FROM imageset
		WHERE user_uID=1
		*/
	
		$dbCon = db::singleton();
		
		$sql = "SELECT isID, name, private, license FROM " . SYS_DB_DBNAME . ".imageset WHERE user_uID=" . $dbCon->real_escape_string($userObj->getuID());
		
		$result = $dbCon->single($sql);
		
		return $result;
	}
	
	public static function getGroupLists($gID){
		/*
		SELECT isID, name, private, license
		FROM imageset
		WHERE group_gID=1
		*/
	
		$dbCon = db::singleton();
		
		$sql = "SELECT * FROM " . SYS_DB_DBNAME . ".imageset WHERE group_gID=" . $dbCon->real_escape_string($gID);
		
		$result = $dbCon->single($sql);
		
		return $result;
	
	}
	

	public static function getListImages($isID){
		/*
		SELECT image.imgID, image.imageURL, image.name, image.license, image.private, imageset.name as setName
		FROM image
		LEFT JOIN image_imageset ON image.imgID=image_imageset.image_imgID
		LEFT JOIN imageset ON imageset.isID=image_imageset.imageset_isID
		WHERE image_imageset.imageset_isID=1	
		*/
		
		$dbCon = db::singleton();
		
		$sql = "SELECT image.imgID, image.imageURL, image.name, image.license, image.private, imageset.name as setName FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image_imageset ON image.imgID=image_imageset.image_imgID LEFT JOIN " . SYS_DB_DBNAME . ".imageset ON imageset.isID=image_imageset.imageset_isID WHERE image_imageset.imageset_isID=" . $dbCon->real_escape_string((int)$isID);
	
		$result = $dbCon->single($sql);
		
		return $result;
	}
	
	public static function searchUserImages(user &$userObj, $searchTerm){
		/*
		SELECT image.imgID, image.imageURL, image.name
		FROM image
		JOIN imageset ON imageset.user_uID=1
		JOIN image_imageset ON imageset.isID = image_imageset.imageset_isID
		WHERE image.imgID = image_imageset.image_imgID AND image.name LIKE "%img%"		
		*/
		$dbCon = db::singleton();
		
		$sql = "SELECT image.imgID, image.imageURL, image.name FROM " . SYS_DB_DBNAME . ".image JOIN imageset ON imageset.user_uID=" . $dbCon->real_escape_string($userObj->getuID()) . " JOIN image_imageset ON imageset.isID = image_imageset.imageset_isID WHERE image.imgID = image_imageset.image_imgID AND image.name LIKE \"%" . $dbCon->real_escape_string($searchTerm) . "%\"";

		$res = $dbCon->single($sql);
		
		return $res;
	
	}

	public static function searchGroupImages(user &$userObj, $gID, $searchTerm){
		/*
		SELECT image.imgID, image.imageURL, image.name
		FROM image
		JOIN imageset ON imageset.group_gID=1
		JOIN image_imageset ON imageset.isID = image_imageset.imageset_isID
		WHERE image.imgID = image_imageset.image_imgID AND image.name LIKE "%img%"		
		*/
		$dbCon = db::singleton();
		
		$sql = "SELECT image.imgID, image.imageURL, image.name FROM " . SYS_DB_DBNAME . ".image JOIN imageset ON imageset.group_gID=" . $dbCon->real_escape_string((int)$gID) . " JOIN image_imageset ON imageset.isID = image_imageset.imageset_isID WHERE image.imgID = image_imageset.image_imgID AND image.name LIKE \"%" . $dbCon->real_escape_string($searchTerm) . "%\"";

		$res = $dbCon->single($sql);
		
		return $res;
	
	}
	
	public static function storeImage(user &$userObj){
		// Steps
		// 1. Save to filesystem (/imageStore/uID/iID.ext), create directory if required
		// 2. Save to database
		
		$dbCon = db::singleton();
		
		if(isset($_FILES['image'])){
			preg_match("/([^.]+)$/", $_FILES['image']['name'], $matches);
			
			if(count($matches) == 0) throw new PicBoardException("No filename detected.");
			
			$ft = $matches[1];
			
			// Are we allowing this filetype?
			if( in_array(strtolower($ft), images::$allowedFiletypes) ){
				if( file_exists(SYS_IMGSTORE . $userObj->getuID()) == false ) mkdir(SYS_IMGSTORE . $userObj->getuID());
				
				// Move the uploaded file
				$newName = md5($_POST['fileName'] . time());
				$newPath = SYS_IMGSTORE . $userObj->getuID() . "/" . $newName . "." . $ft;
				$newURL = SYS_BASEURL . "imageStore/" . $userObj->getuID() . "/" . $newName . "." . $ft;
				
				if(!move_uploaded_file($_FILES['image']['tmp_name'], $newPath)){
					throw new PicBoardException("Unable to move uploaded file to target directory");
				}
				
				$visiblity = ($_POST['image_private'] == "visible") ? 0 : 1;
				
				$sql = "INSERT INTO " . SYS_DB_DBNAME . ".image (imageURL, name, license, private, originator_uID) VALUES('" . $dbCon->real_escape_string($newURL) . "', '" . $dbCon->real_escape_string($_POST['fileName']) . "', '', '" . $visiblity . "', " . $userObj->getuID() . ");";
				
				$dbCon->single($sql);
				
				if((int)$_POST['fileSaveLocations'] != 0){
					$sql = "INSERT INTO " . SYS_DB_DBNAME . ".image_imageset(image_imgID, imageset_isID) VALUES(" . $dbCon->insert_id . "," . $dbCon->real_escape_string((int)$_POST['fileSaveLocations']) . ")";
					$dbCon->single($sql);
				}
				
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
	
	public static function storeGroupImage(user &$userObj, $gID){
		if($userObj->getAccessLevel() < 0) throw new PicBoardException("Unauthorised");
		if($userObj->isInGroup($gID)){
		
			$dbCon = db::singleton();
			
			if(isset($_FILES['image'])){
			
				preg_match("/([^.]+)$/", $_FILES['image']['name'], $matches);
				
				if(count($matches) == 0) throw new PicBoardException("No filename detected.");
				
				$ft = $matches[1];
				
				// Are we allowing this filetype?
				if( in_array(strtolower($ft), images::$allowedFiletypes) ){
					if( file_exists(SYS_IMGSTORE . "g-" . $dbCon->real_escape_string($gID)) == false ) mkdir(SYS_IMGSTORE . "g-" . $dbCon->real_escape_string($gID));
					
					// Move the uploaded file
					$newName = md5($_POST['fileName'] . time());
					$newPath = SYS_IMGSTORE . "g-" . $dbCon->real_escape_string($gID) . "/" . $newName . "." . $ft;
					$newURL = SYS_BASEURL . "imageStore/g-" . $dbCon->real_escape_string($gID) . "/" . $newName . "." . $ft;
					
					if(!move_uploaded_file($_FILES['image']['tmp_name'], $newPath)){
						throw new PicBoardException("Unable to move uploaded file to target directory");
					}
					
					$visiblity = 1;
					
					$sql = "INSERT INTO " . SYS_DB_DBNAME . ".image (imageURL, name, license, private, originator_uID) VALUES('" . $dbCon->real_escape_string($newURL) . "', '" . $dbCon->real_escape_string($_POST['fileName']) . "', '', '" . $visiblity . "', " . $userObj->getuID() . ");";
					
					$dbCon->single($sql);
					
					if((int)$_POST['fileSaveLocations'] != 0){
						$sql = "INSERT INTO " . SYS_DB_DBNAME . ".image_imageset(image_imgID, imageset_isID) VALUES(" . $dbCon->insert_id . "," . $dbCon->real_escape_string((int)$_POST['fileSaveLocations']) . ")";
						$dbCon->single($sql);
					}
					
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}	
		
		
		} else {
			return false;
		}	
	}
	
	public static function deleteImage(user &$userObj, $imgID){
		// Delete record from the database
		// Delete file from filesystem
		
		/*
		SELECT image.imgID, image.imageURL, imageset.group_gID
		FROM image
		LEFT JOIN image_imageset ON image.imgID=image_imageset.image_imgID
		LEFT JOIN imageset ON imageset.isID=image_imageset.imageset_isID
		WHERE image.imgID=3 AND imageset.user_uID=1
		*/

		if($userObj->getAccessLevel() < 0) throw new PicBoardException("Unauthorised");

		$dbCon = db::singleton();
		
		$dbCon->startTransaction();
		
		try {
		
			
			$sql = "SELECT image.imgID, image.imageURL, imageset.group_gID FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image_imageset ON image.imgID=image_imageset.image_imgID LEFT JOIN " . SYS_DB_DBNAME . ".imageset ON imageset.isID=image_imageset.imageset_isID WHERE image.imgID=" . $dbCon->real_escape_string((int)$imgID);
		
			$res = $dbCon->oneRow($sql);
			
			if(count($res)> 0){
			
				if(isset($res['group_gID'])){
					// This belongs to a group.
					$managedGroups = $userObj->getManagedGroups();
					
					
					$auth = false;
					foreach($managedGroups as $group){
						if($group[0] == $res['group_gID']) $auth = true;
					}
					
					if($auth == false) throw new PicBoardException("You are not allowed to delete this image. Please ask an administrator of the group.");
				}
			
			
				$linkField = "DELETE FROM " . SYS_DB_DBNAME . ".image_imageset WHERE image_imgID=" . $dbCon->real_escape_string($res['imgID']);
				$image = "DELETE FROM " . SYS_DB_DBNAME . ".image WHERE imgID=" . $dbCon->real_escape_string($res['imgID']);
				
				$dbCon->single($linkField);
				$dbCon->single($image);
				
				// Delete the file
				
				preg_match("/\/([\w|\d|\.]+)$/", $res['imageURL'], $matches);
				if(count($matches) > 1){
				
					// If there are clones we do not want to delete this file.
					$clones = images::getClones($userObj, $imgID);
					
					if(count($clones) == 0){				
						if(isset($res['group_gID'])){
							unlink(SYS_IMGSTORE . "g-" . $dbCon->real_escape_string($res['group_gID']) . "/" . $matches[1]);
						} else {
							unlink(SYS_IMGSTORE . $userObj->getuID() . "/" . $matches[1]);
						}
					}
				}
			} else {
				$dbCon->rollback();
				return false;
			}
				
			$dbCon->commit();	
			return true;
		} catch(Exception $e){
			$dbCon->rollback();
			return false;
		}

	}
	
	public static function deleteImageSet(user &$userObj, $isID){
		if($userObj->getAccessLevel() < 0) throw new PicBoardException("Unauthorised");
		
		/*
		SELECT group_gID, user_uID
		FROM imageset
		WHERE isID=4		
		*/



		$dbCon = db::singleton();

		$dbCon->startTransaction();

		try {

			$sql = "SELECT group_gID, user_uID FROM " . SYS_DB_DBNAME . ".imageset WHERE isID=" . $dbCon->real_escape_string((int)$isID);
			
			$res = $dbCon->oneRow($sql);
			
			// Is this a group imageset?
			if(isset($res['group_gID'])){
				// This belongs to a group.
				$managedGroups = $userObj->getManagedGroups();
				
				
				$auth = false;
				foreach($managedGroups as $group){
					if($group[0] == $res['group_gID']) $auth = true;
				}
				
				if($auth == false) throw new PicBoardException("You are not allowed to delete this image. Please ask an administrator of the group.");
			}
			
			// Get a list of the images that are associated with this imageset
			
			$images = images::getListImages($isID);
			
			
			// Delete the images
			foreach($images as $image){
				images::deleteImage($userObj, $image['imgID']);
			}
			
			// Delete the imageset
			$sql = "DELETE FROM " . SYS_DB_DBNAME . ".imageset WHERE isID=" . $dbCon->real_escape_string((int)$isID);
			
			$dbCon->single($sql);
		
			$dbCon->commit();
			return true;
		} catch (Exception $e){
			$dbCon->rollback();
			return false;
		}

	}
	
	public static function createImageSet(user &$userObj, $name, $description, $private){
		if($userObj->getAccessLevel() < 0) throw new PicBoardException("Unauthorised");
		
		if($name == "") return false;
		
		$dbCon = db::singleton();
		
		// Is the name unique?
		if(album::nameExists($userObj, $name)) throw new PicBoardException("You cannot use this name as it is already in use");		
		
		$dbCon->startTransaction();
		
		try {
		
			$sql = "INSERT INTO " . SYS_DB_DBNAME . ".imageset (user_uID, originator_uID, name, description, private) VALUES(" . $userObj->getuID() . "," . $userObj->getuID() . ",'" . $dbCon->real_escape_string($name) . "', '" . $dbCon->real_escape_string($description) . "', " . $dbCon->real_escape_string($private) . ")";
			$dbCon->single($sql);
			
			$dbCon->commit();
			return true;
		} catch (Exception $e){
			$dbCon->rollback();
			return false;
		}
	}
	
	public static function createGroupImageSet(user &$userObj, $name, $description, $visibility, $groupID){
		if($userObj->getAccessLevel() < 0) throw new PicBoardException("Unauthorised");
		if($userObj->isInGroup($groupID)){
		
		
			if($name == "") return false;
			
			// Is the name unique?
			if(album::nameExists($userObj, $name, album::LOCATION_GROUP, $groupID)) throw new PicBoardException("You cannot use this name as it is already in use");			
			
			$dbCon = db::singleton();
			
			$dbCon->startTransaction();
			
			try {
			
				$sql = "INSERT INTO " . SYS_DB_DBNAME . ".imageset (originator_uID, group_gID, name, description, private) VALUES(" . $userObj->getuID() . "," . $dbCon->real_escape_string($groupID). ",'" . $dbCon->real_escape_string($name) . "', '" . $dbCon->real_escape_string($description) . "', " . $dbCon->real_escape_string($visibility) . ")";
				$dbCon->single($sql);
				
				$dbCon->commit();
				return true;
			} catch (Exception $e){
				$dbCon->rollback();
				return false;
			}			
		
		} else {
			return false;
		}
	}

	public static function nameExists(user &$userObj, $name, $libraryID){
		$dbCon = db::singleton();
		

		$sql = "SELECT COUNT(*) FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image_imageset AS link ON image.imgID=link.image_imgID LEFT JOIN " . SYS_DB_DBNAME . ".imageset ON link.imageset_isID=imageset.isID WHERE imageset.isID = " . $dbCon->real_escape_string($libraryID) . " AND image.name LIKE '" . $dbCon->real_escape_string($name) . "'";
		$res = $dbCon->oneRow($sql);
		
		return (BOOL)$res['COUNT(*)'];
	}	
	
	public static function generateFormattedUserLists(&$userObj){
		$lists = images::getUserLists($userObj);
		
		$itemTemplate = new template('fragment.compactListItem');
		
		$imagesOutput = "<h3><var id=\"lang_179_myImageSets\"></var></h3>";
		
		foreach($lists as $imageset){
			$out = "<a href='#' class='selectableImageSet' id='is" . $imageset['isID'] . "'>" . $imageset['name'] . "</a>";

			$itemTemplate->replace("desc", $out);
			$imagesOutput .= $itemTemplate->get();
			$itemTemplate->reset();		
		}
		
		return $imagesOutput;
	}
	
	public static function generateFormattedUserListImages(&$useObj, $isID){
		$images = images::getListImages($isID);
				
		$itemTemplate = new template('fragment.imageHolder');
		
		if(count($images) > 0){
		
			$imagesOutput = "<h3>" . $images[0]['setName'] . "</h3><div id=\"imageSelectableHolder\">";
			
			foreach($images as $image){
	
				$itemTemplate->replace("text", $image['name']);
				$itemTemplate->replace("img", "<img src=\"" . $image['imageURL'] . "\" id='i" . $image['imgID'] . "' height=\"50\" width=\"50\">");
				$imagesOutput .= $itemTemplate->get();
				$itemTemplate->reset();		
			}
			
			return $imagesOutput . "</div>";
		} else {
			return "";
		}
	}
	
	public static function getImage($imgID){
		/*
		SELECT image.*, user.username, imageset.name AS albumName, imageset.group_gID, imageset.isID, imageset.originator_uID AS albumOriginator
		FROM image
		LEFT JOIN image_imageset ON image.imgID = image_imageset.image_imgID
		LEFT JOIN imageset ON imageset.isID = image_imageset.imageset_isID
		LEFT JOIN user ON imageset.user_uID = user.uID
		WHERE imgID=13
		*/
		$dbCon = db::singleton();
		
		$sql = "SELECT image.*, user.username, user.uID, imageset.name AS albumName, imageset.group_gID, imageset.isID, imageset.originator_uID AS albumOriginator FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image_imageset ON image.imgID = image_imageset.image_imgID LEFT JOIN " . SYS_DB_DBNAME . ".imageset ON imageset.isID = image_imageset.imageset_isID LEFT JOIN " . SYS_DB_DBNAME . ".user ON imageset.user_uID = user.uID WHERE imgID=" . $dbCon->real_escape_string((int)$imgID);
	
		return $dbCon->oneRow($sql);
	}
	
	public static function getGroupImages(user &$userObj, $gID){
		return images::searchGroupImages($userObj, $gID, "");
	}
	
	public static function getUserImages(user &$userObj){
		return images::searchUserImages($userObj, "");
	}
	
	public static function updateImageDetails(user &$userObj, $imgID, $name, $description){
		$imgID = (int)$imgID;
		
		if($imgID == 0) throw new PicBoardException("Image ID must be an integer");
		
		// Checks
		$stored_image = images::getImage($imgID);
		if($stored_image['name'] != $name){	
			if(images::nameExists($userObj, $name, $stored_image['isID'])) throw new PicBoardException("You cannot use this name as an image with the same name already exists in this library.");
		}
		
		$dbCon = db::singleton();
		
		$sql = "UPDATE " . SYS_DB_DBNAME . ".image SET name='" . $dbCon->real_escape_string($name) . "', description='" . $dbCon->real_escape_string($description) . "' WHERE imgID=" . $dbCon->real_escape_string($imgID);
	
		$dbCon->single($sql);
	}
	
	public static function getClones(user &$userObj, $originalID, $location = images::LOCATION_ALL, $locationid = 0){
		$dbCon = db::singleton();
		
		switch($location){
			case images::LOCATION_ALL:
				$sql = "SELECT * FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image_imageset ON image.imgID=image_imageset.image_imgID LEFT JOIN " . SYS_DB_DBNAME . ".imageset ON image_imageset.imageset_isID=imageset.isID LEFT JOIN " . SYS_DB_DBNAME . ".group ON imageset.group_gID = group.gID WHERE image.originator_uID=" . $userObj->getuID() . " AND clone_of=" . $dbCon->real_escape_string((int)$originalID);
			break;
			
			case images::LOCATION_GROUP:
				if($locationid == 0){
					$sql = "SELECT * FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image_imageset ON image.imgID=image_imageset.image_imgID LEFT JOIN " . SYS_DB_DBNAME . ".imageset ON image_imageset.imageset_isID=imageset.isID LEFT JOIN " . SYS_DB_DBNAME . ".group ON imageset.group_gID = group.gID WHERE image.originator_uID=" . $userObj->getuID() . " AND clone_of=" . $dbCon->real_escape_string((int)$originalID) . " AND imageset.group_gID IS NOT NULL";
				} else {
					$sql = "SELECT * FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image_imageset ON image.imgID=image_imageset.image_imgID LEFT JOIN " . SYS_DB_DBNAME . ".imageset ON image_imageset.imageset_isID=imageset.isID LEFT JOIN " . SYS_DB_DBNAME . ".group ON imageset.group_gID = group.gID WHERE image.originator_uID=" . $userObj->getuID() . " AND clone_of=" . $dbCon->real_escape_string((int)$originalID) . " AND imageset.group_gID=" . $dbCon->real_escape_string((int)$locationid);
				}
			break;
		}
		$result = $dbCon->single($sql);
		
		return $result;
	}
	
	public static function getOriginalID($cloneID){
		$dbCon = db::singleton();
		
		$sql = "SELECT original.imgID FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".image AS original ON image.clone_of=original.imgID WHERE image.imgID=" . $dbCon->real_escape_string((int)$cloneID);
		
		$result = $dbCon->oneRow($sql);
		
		return (int) $result['imgID'];
	}
	
	public static function getPath($imgID){
		$image = images::getImage($imgID);
		
		$path = $image['imageURL'];
		
		$path = str_replace(SYS_BASEURL, SYS_IMGSTORE, $path);
	}
	
	public static function cloneImage(user &$userObj, $originalID, $location, $destinationISID){
		if($location != images::LOCATION_USER && $location != images::LOCATION_GROUP) throw new PicBoardException("Location must be of type images::LOCATION_USER or images::LOCATION_GROUP");
	
		// Duplication of images.
		
		$dbCon = db::singleton();
		
		// Get the current image information
		
		$image = images::getImage($originalID);
		
		$dbCon->startTransaction();
		
		try {
		
			$originator = ($image['originator_uID'] != "") ? $image['originator_uID'] : $image['user_uID'];
			$clone = ($image['clone_of'] != "") ? $image['clone_of'] : $image['imgID'];
			
			// We need to insert this information into a new record.
			$sql = "INSERT INTO " . SYS_DB_DBNAME . ".image (imageURL, name, description, license, private, originator_uID, clone_of) VALUES ('" . $dbCon->real_escape_string($image['imageURL']) . "', '" . $dbCon->real_escape_string($image['name']) . "', '" . $dbCon->real_escape_string($image['description']) . "', '" . $dbCon->real_escape_string($image['license']) . "', " . $dbCon->real_escape_string($image['private']) . ", " . $dbCon->real_escape_string($originator) . ", " . $dbCon->real_escape_string($clone) . ");";
		
			// Save new location to database.
			
			$dbCon->single($sql);
			
			// Link to new imageset
			$sql = "INSERT INTO " . SYS_DB_DBNAME . ".image_imageset (image_imgID, imageset_isID) VALUES(" . $dbCon->real_escape_string($dbCon->insert_id) . ", " . $dbCon->real_escape_string($destinationISID) . ")";
	
			$dbCon->single($sql);
	
			$dbCon->commit();
			return true;
		} catch(Exception $e){
			$dbCon->rollback();
		}
	}	

	public static function getOriginator($imageID){
		$dbCon = db::singleton();

		$sql = "SELECT image.originator_uID, user.uID, user.userName FROM " . SYS_DB_DBNAME . ".image LEFT JOIN " . SYS_DB_DBNAME . ".user ON image.originator_uID = user.uID WHERE imgID=" . $dbCon->real_escape_string((int)$imageID);

		$result = $dbCon->oneRow( $sql );
		
		return $result;	
	}	
	
	public static function retrieveFromGroup(user &$userObj, $imageID, $groupID, $locationID){
		$dbCon = db::singleton();
		
		// Steps we need:
		// Does the original exist?
		$originalID = images::getOriginalID($imageID);
		$originalImage = images::getImage($originalID);
		
		// Do we need to clone the image?
		if(count($originalImage) == 0){
			images::cloneImage($userObj, $imageID, images::LOCATION_USER, $locationID);
		} elseif($originalImage['uID'] != $userObj->getuID()) {
			images::cloneImage($userObj, $imageID, images::LOCATION_USER, $locationID);
		}

		// Delete the image
		images::deleteImage($userObj, $imageID);
		
		return true;
		
	}
	
} 

?>